package cn.laoma.thread2.t2_001;

/**
 * @program: ThreadDemos
 * @description: voldtile DCL-Double check lock. 如果不加volatile,会受到指令重拍的困扰
 * 这里看下 为什么DCL要加Volatile.jpg
 * 注意synchronized 和 volatile的有序性不一样：
 * synchronized 的有序性：
 *      是持有相同锁的两个同步块只能串行的进入，即被加锁的内容要按照顺序被多个线程执行，
 *      但是其内部的同步代码还是会发生重排序，使块与块之间有序可见。
 * volatile的有序性：
 *      是通过插入内存屏障来保证指令按照顺序执行。不会存在后面的指令跑到前面的指令之前来执行。
 *      是保证编译器优化的时候不会让指令乱序。
 *
 * @author: 老马
 * @create: 2021-01-24 20:33
 **/
public class Volatile_02DCLTest {
    private static /*volatile*/ Volatile_02DCLTest instance;

    public static Volatile_02DCLTest getInstance() {
        //可以看到加了两个instance == null的判断，主要是为了提高效率，
        // 如果最外面的instance == null不要的话，每次获取对象的时候都需要进行加锁操作，比较耗时间
        if(instance == null) {
            synchronized (Volatile_02DCLTest.class) {
                if(instance == null) {
                    instance = new Volatile_02DCLTest();
                }
            }
        }
        return instance;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(() -> System.out.println(Volatile_02DCLTest.getInstance().hashCode())).start();
        }
    }
}
